/****************************************************************************
Copyright (c) 2010-2013 cocos2d-x.org
Copyright (c) Microsoft Open Technologies, Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/


#ifndef GAMEMODEL_H
#define GAMEMODEL_H

#include <string>

using namespace std;

///@class GameModel The model of game chess board.
///@brief
class GameModel
{
public:
    ///The moving directions
    static const int LEFT=0, ///<move left
        RIGHT=4, ///<move right
        UP=1, ///<move up
        DOWN=3; ///<move down

    ///@brief Constructor with size of chess board.
    GameModel(int size);
    ///@brief Distructor
    virtual ~GameModel();
    ///@brief Get the size of chess board
    int getSize();
    ///@brief Get the block id with specific row and col.
    ///return >0 if the block exists, or -1 when error.
    int getData(int row,int col);
    ///@brief Get the location of sapce block.
    ///@param row Output of row
    ///@param col Output of col
    void getSpaceLoc(int &row,int &col);
    ///@brief Get the location of specific block.
    ///@param row Output of row
    ///@param col Output of col
    ///@param val The block id.
    void getDataLoc(int& row,int& col,int val);

    ///@brief Move the block by specific direction
    ///@param direction
    ///@see LEFT,RIGHT,UP,DOWN
    bool moveByDirection(int direction);

    ///@brief Move the block at specific row and col.
    ///@return
    ///@retval true Can move
    bool moveByRowCol(int row,int col);

    ///@brief Judge whether the block can move.
    bool judgeByRowCol(int row,int col);

    ///@brief Judge whether the game is win.
    bool judgeWin();

    ///@brief Confuse the places of all blocks.
    ///@param nStep Moves when initiation.
    void random(const int nStep);

    ///@brief Load all block ids from an array.
    bool loadData(int dd[]);

    ///@brief Pull the data of block ids to a string.
    string pullData();

    ///@brief Push the data from a string to memory.
    bool pushData(string str);

    ///@brief Print the data of game chess board.
    string toString();


protected:
    int *data; ///<Game chess board data.
    int _size; ///<Game chess board size.
    int dataSize; ///<Count of data.
    int spaceRow; ///<Row of space block.
    int spaceCol; ///<Col of space block.

private:
    inline void swap(int id1,int id2);
};

#endif // GAMEMODEL_H
